﻿using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp.Demos.SimplePipeline
{
    public static class Run
    {
        public static void DoIt()
        {
            Host.CreateDefaultBuilder()
                // 从框架拿到 IHostBuilder <WebHostBuilder>
                .ConfigureWebHostByCustom(webHostBuilderByCustom =>
                {
                    // 方法内部会创建一个 WebHostBuilderByCustom
                    // 然后执行 Invoke 配置

                    // 一种编程模式
                    // 一般在方法内部先构造 Invoke 需要的参数
                    // 然后执行 Invoke（外部配置）
                    // 最后拿到外部配置的信息，进行初始化

                    // WebHostBuilderByCustom 有两个属性
                    //    IHostBuilder <WebHostBuilder>
                    //    IApplicationBuilderByCustom <WebHostBuilderByCustom>

                    // 拿到这两个属性之后，就开始相关构建了

                    webHostBuilderByCustom
                    // 在 webHostBuilderByCustom 的 IHostBuilder 属性的 Services 属性中添加一个 Singleton 生命周期的 IServerByCustom <HttpListenerServerByCustom> 对象
                    // 由于不需要额外配置，此次就没有设置 Lambda 参数
                    .UseHttpListenerServerByCustom()
                    .ConfigureByCustom(applicationBuilderByCustom =>
                    {
                        // 将自定义的 Middleware，添加到一个中间件列表中
                        // 中间件列表类型为 IList<Func<RequestDelegateByCustom, RequestDelegateByCustom>>
                        applicationBuilderByCustom.UseByCustom(FooMiddleware);
                        applicationBuilderByCustom.UseByCustom(BarMiddleware);
                        applicationBuilderByCustom.UseByCustom(BazMiddleware);
                    });
                })
                // 参数都配置好了，调用 IHostBuilder.Build()
                .Build()
                // 最后执行 IHost.Run()
                // 也就是触发 HttpListenerServerByCustom.StartAsync 
                .Run();
        }

        public static RequestDelegateByCustom FooMiddleware(RequestDelegateByCustom next)
            => async context =>
             {
                 await context.Response.WriteAsyncByCustom("Foo=>");
                 await next(context);
             };

        public static RequestDelegateByCustom BarMiddleware(RequestDelegateByCustom next)
            => async context =>
            {
                await context.Response.WriteAsyncByCustom("Bar=>");
                await next(context);
            };

        public static RequestDelegateByCustom BazMiddleware(RequestDelegateByCustom next)
            => async context =>
            {
                await context.Response.WriteAsyncByCustom("Baz");
                // 不继续执行后续的 next 了
                // await next(context);
            };
    }
}
